﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.IO;
using System.Globalization;

namespace CoolCode.Web.UI
{
    public static class ControlExtensions
    {
        /// <summary>
        /// 重置当前控件里所有子控件的值
        /// </summary>
        /// <param name="control"></param>
        public static void Reset(this Panel control)
        {
            IControlBinder binder = null;
            if (control.Page is IControlBindable)
            {
                binder = ((IControlBindable)control.Page).ControlBinder;
            }
            else
            {
                binder = new ControlBinder();
            }
            binder.InitialValue(control);
        }

        public static T FindControl<T>(this Control control, string id) where T : class
        {
            Control c = control.FindControl(id);
            return (c as T);
        }


        public static List<T> FindControls<T>(this Control control) where T : Control
        {
            Action<Control, List<T>> findhelper = null;
            findhelper = (ctl, list) =>
           {
               if (ctl is T)
               {
                   list.Add((T)ctl);
               }
               if (ctl.HasControls())
               {
                   foreach (Control c in ctl.Controls)
                   {
                       findhelper(c, list);
                   }
               }
           };
            List<T> controls = new List<T>();
            findhelper(control, controls);
            return controls;
        }

        #region SetText : SPC

        public static void SetText(this IButtonControl control, Language language)
        {
            string key = ((Control)control).ID.ToUpper();
            if (language != null && language.ContainsKey(key))
            {
                control.Text = language[key];
            }
        }

        public static void SetText(this Control control, Language language)
        {
            string key = ((Control)control).ID.ToUpper();
            if (language != null && language.ContainsKey(key))
            {
                var p = control.GetType().GetProperty("Text");
                if (p != null)
                    p.SetValue(control, language[key], null);
            }
        }

        public static void SetText(this GridViewRow row, Language language, params string[] controlsID)
        {
            if (controlsID == null) return;
            foreach (string id in controlsID)
            {
                Control c = row.FindControl(id);
                if (c != null)
                    c.SetText(language);
            }
        }

        public static void SetText(this GridView grid, Language language)
        {
            string tableName = grid.Attributes["TableName"];
            if (!string.IsNullOrEmpty(tableName))
            {
                SetText(grid, language, tableName);
            }
            else
                SetText(grid, language, String.Empty);
        }

        public static void SetText(this GridView grid, Language language, string tableName)
        {
            foreach (DataControlField col in grid.Columns)
            {
                if (col is BoundField)
                {
                    BoundField f = (BoundField)col;
                    string key;
                    if (tableName == String.Empty)
                        key = f.DataField;
                    else
                        key = tableName + "." + f.DataField;
                    key = key.ToUpper();
                    if (language.ContainsKey(key))
                        col.HeaderText = language[key];
                }
                //else if (col is ButtonField)
                //{
                //    ButtonField f = (ButtonField)col;
                //    string key = f.CommandName.ToUpper();
                //    if (spc.ContainsKey(key))
                //        f.Text = spc[key];

                //}
                //else if (col is TemplateField)
                //{
                //    TemplateField f = (TemplateField)col;
                //    if (!string.IsNullOrEmpty(f.SortExpression))
                //    {
                //        string key = f.SortExpression.ToUpper();
                //        if (spc.ContainsKey(key))
                //            f.HeaderText = spc[key];
                //    } 
                //}
            }
        }

        #endregion

        #region Control Lookup

        private static Func<Control, bool> validIdCondiction = c =>
        {
            return (!string.IsNullOrEmpty(c.ID)) && (c.ID == c.ClientID || c.ClientID.EndsWith("_" + c.ID));
        };

        /// <summary>
        /// 获取所有的控件，不包括ID为null的控件
        /// </summary>
        /// <param name="container"></param>
        /// <returns></returns>
        public static List<Control> GetControls(this Control container)
        {
            return GetAllControls(container).Where(validIdCondiction).ToList();

        }

        /// <summary>
        /// 获取所有asp.net标准控件，不包括ID为null的控件，不包括用户控件以及用户控件的子控件 
        /// </summary>
        /// <param name="container"></param>
        /// <returns></returns>
        public static List<Control> GetStandardControls(this Control container)
        {
            return GetAllControls(container, false).Where(validIdCondiction).ToList();
        }

        /// <summary>
        /// 获取所有的控件，包括ID为null的控件
        /// </summary> 
        /// <returns></returns>
        public static List<Control> GetAllControls(this  Control container)
        {
            return GetAllControls(container, true);
        }

        /// <summary>
        /// 获取所有的控件，包括ID为null的控件
        /// </summary> 
        /// <returns></returns>
        public static List<Control> GetAllControls(this Control container, bool includeUserControl)
        {
            List<Control> cs = new List<Control>();
            getAllControls(cs, container, includeUserControl);
            return cs;
        }

        private static void getAllControls(List<Control> cs, Control container, bool includeUserControl)
        {
            foreach (Control c in container.Controls)
            {
                if (!includeUserControl && c is UserControl)
                    continue;
                cs.Add(c);
                if (c.HasControls())
                    getAllControls(cs, c, includeUserControl);
            }
        }

        #endregion

        public static void Bind(this ListControl control, IList<ValueText> list)
        {
            control.DataTextField = "Text";
            control.DataValueField = "Value";
            control.DataSource = list;
            control.DataBind();
        }

        public static void Bind(this ListControl control, IList<string> list)
        {
            control.DataSource = list;
            control.DataBind();
        }

        public static void SetSelections(this ListControl control, IList<string> list)
        {
            foreach (ListItem item in control.Items)
            {
                if (list.Contains(item.Value))
                {
                    item.Selected = true;
                }
                else
                {
                    item.Selected = false;
                }
            }
        }

        public static List<string> GetSelections(this ListControl control)
        {
            List<string> selectedList = new List<string>();
            foreach (ListItem item in control.Items)
            {
                if (item.Selected)
                {
                    selectedList.Add(item.Value);
                }
            }
            return selectedList;
        }

        public static int GetRowIndex(this GridViewCommandEventArgs e)
        {
            GridViewRow gvrow = (GridViewRow)(((Control)e.CommandSource).NamingContainer);
            return gvrow.RowIndex;
        }

        public static T GetKey<T>(this GridView grid, int rowIndex)
        {
            T key = (T)grid.DataKeys[rowIndex].Value;
            return key;
        }


        public static void HandleSelectAll(this GridView grid, string selectAllCheckBox, string selectCheckBox)
        {
            grid.RowDataBound += (sender, e) =>
            {
                if (e.Row.RowType == DataControlRowType.Header)
                {
                    CheckBox chkSelectAll = (CheckBox)e.Row.FindControl(selectAllCheckBox);
                    chkSelectAll.Attributes.Add("onclick", "selectAll('" + chkSelectAll.ClientID + "','" + selectCheckBox + "')");
                }
            };
        }

        public static List<T> GetSelections<T>(this GridView grid, string checkboxID, int columnID)
        {
            List<T> selected = new List<T>();
            Type type = typeof(T);
            foreach (GridViewRow gvr in grid.Rows)
            {
                CheckBox chk = gvr.FindControl(checkboxID) as CheckBox;
                if (chk != null)
                {
                    if (chk.Checked)
                    {
                        string key = gvr.Cells[columnID].Text;
                        T t = (T)Convert.ChangeType(key, type);
                        selected.Add(t);
                    }
                }
            }
            return selected;
        }

        public static void SelectAll(this GridView grid, string checkboxID)
        {
            selectHelper(grid, checkboxID, true);
        }

        public static void UnSelectAll(this GridView grid, string checkboxID)
        {
            selectHelper(grid, checkboxID, false);
        }

        private static void selectHelper(this GridView grid, string checkboxID, bool checkflag)
        {
            foreach (GridViewRow gvr in grid.Rows)
            {
                CheckBox chk = gvr.FindControl(checkboxID) as CheckBox;
                if (chk != null)
                {
                    chk.Checked = checkflag;
                }
            }
        }

        public static bool IsSelected(this GridViewRow gvr, string checkboxID)
        {
            CheckBox chk = gvr.FindControl(checkboxID) as CheckBox;
            return (chk != null && chk.Checked);
        }

        public static void DisableCommand(this GridView grid, Role role)
        {
            List<string> commands = new List<string>();
            if (!role.AllowEdit) commands.Add("lnkEdit");
            if (!role.AllowDelete) commands.Add("lnkDelete");
            grid.DisableCommand(commands.ToArray());
        }

        public static void DisableCommand(this GridView grid, params  string[] commands)
        {
            if (commands == null || commands.Length == 0) return;
            grid.RowDataBound += (sender, e) =>
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    commands.ForEach(c =>
                    {
                        WebControl control = e.Row.FindControl(c) as WebControl;
                        if (control != null)
                        {
                            control.Enabled = false;
                        }
                    });
                }
            };
        }

        public static string ToHtml(this Control control)
        {
            StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

            control.RenderControl(htmlWriter);
            htmlWriter.Flush();
            htmlWriter.Close();

            return stringWriter.ToString();
        }

        ///// <summary>
        ///// 设置分页控件，填充空白行
        ///// </summary>
        ///// <param name="grid"></param>
        ///// <param name="pager">分页控件</param>
        //public static void Plug(this GridView grid, IPager pager)
        //{
        //    grid.RowDataBound += (sender, e) =>
        //    {
        //        if (e.Row.RowType == DataControlRowType.Footer || e.Row.RowType == DataControlRowType.EmptyDataRow)
        //        {
        //            //当Gridview行不足时，填充空白行
        //            for (int i = 0; i < pager.PageSize - grid.Rows.Count; i++)
        //            {
        //                int rowIndex = grid.Rows.Count + i + 1;
        //                GridViewRow row = new GridViewRow(rowIndex, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
        //                TableCell cell = new TableCell();
        //                cell.Text = "&nbsp;";
        //                cell.ColumnSpan = grid.Columns.Count;
        //                row.Controls.Add(cell);
        //                row.Attributes.Add("style ", "background-color: #ffffff;");
        //                grid.Controls[0].Controls.AddAt(rowIndex, row);
        //            }
        //        }
        //    };
        //}

        ///// <summary>
        ///// 绑定分页数据和分页控件
        ///// </summary>
        ///// <param name="list"></param>
        ///// <param name="bindableControl">能够绑定数据源的控件</param>
        ///// <param name="pager">分页控件</param>
        //public static void Bind(this BaseDataBoundControl bindableControl, IPaginatedList list, IPagingBinder pager)
        //{
        //    bindableControl.DataSource = list;
        //    bindableControl.DataBind();
        //    pager.Bind(list);
        //}
    }

}
